#include "TcpClient.hpp"

using namespace Protocol_ns;

static void usage(std::string proc)
{
    std::cout << "Usage:\n\t" << proc << " serverip serverport\n"
              << std::endl;
}

enum
{
    LEFT,
    OPER,
    RIGHT
};

Request ParseLine(const std::string &line)
{
    std::string left, right;
    char op;
    int status = LEFT;
    int i = 0;
    while (i < line.size())
    {
        switch(status)
        {
            case LEFT:
                if (isdigit(line[i]))
                {
                    left.push_back(line[i++]);
                }
                else
                {
                    status = OPER;
                }
                break;
            case OPER:
                op = line[i++];
                status = RIGHT;
                break;
            case RIGHT:
                if (isdigit(line[i]))
                {
                    right.push_back(line[i++]);
                }
                break;
        }
    }
    Request req;
    std::cout << "left: " << left << std::endl;
    std::cout << "right: " << right << std::endl;
    std::cout << "op: " << op << std::endl;

    req._x = stoi(left);
    req._y = stoi(right);
    req._op = op;

    return req;
}

// ./calclient serverip serverport
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        usage(argv[1]);
        exit(USAGE_ERR);
    }

    std::string serverip = argv[1];
    uint16_t serverport = atoi(argv[2]);

    Sock sock;
    sock.Socket();

    int n = sock.Connect(serverip, serverport);
    if (n != 0)
    {
        return 1;
    }

    std::string inbuffer;
    while (true)
    {
        std::cout << "Enter# ";
        std::string line;
        std::getline(std::cin, line);
        //构造请求报文
        Request req = ParseLine(line);

        std::cout << req._x << req._op << req._y << std::endl;

        //序列化请求报文
        std::string sendstring;
        req.Serialize(&sendstring);
        //给请求报文添加报头
        sendstring = AddHeader(sendstring);
        //send
        send(sock.Fd(), sendstring.c_str(), sendstring.size(), 0);

        //获取响应报文
        std::string package;
        int n = 0;
    START:  
        n = ReadPackage(sock.Fd(), inbuffer, &package);
        if (n == 0)//没有获取到一个完整报文
        {
            goto START;
        }
        else if (n < 0)//没有读取到报文
        {
            break;
        }
        else
        {
            //此时必定获得一个完整报报文
            //去掉报头
            package = RemoveHeader(package, n);

            //将响应报文反序列化
            Response resp;
            resp.Deserialize(package);

            std::cout << "result: " << resp._result << "[code: " << resp._code << "]" << std::endl; 
        }
    }
    sock.Close();
    return 0;
}